#include "../include/server.h"

int count = 0;
int client_id[10] = {0};
int user_id = 0;

unsigned char *base64_decode(unsigned char *code)  
{  
	//根据base64表，以字符找到对应的十进制数据  
	int table[]={0,0,0,0,0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,62,0,0,0,
		63,52,53,54,55,56,57,58,
		59,60,61,0,0,0,0,0,0,0,0,
		1,2,3,4,5,6,7,8,9,10,11,12,
		13,14,15,16,17,18,19,20,21,
		22,23,24,25,0,0,0,0,0,0,26,
		27,28,29,30,31,32,33,34,35,
		36,37,38,39,40,41,42,43,44,
		45,46,47,48,49,50,51
	};  
	long len;  
	long str_len;  
	unsigned char *res;  
	int i,j;  

	//计算解码后的字符串长度  
	len=strlen(code);  
	//判断编码后的字符串后是否有=  
	if(strstr(code,"=="))  
		str_len=len/4*3-2;  
	else if(strstr(code,"="))  
		str_len=len/4*3-1;  
	else  
		str_len=len/4*3;  

	res=malloc(sizeof(unsigned char)*str_len+1);  
	res[str_len]='\0';  

	//以4个字符为一位进行解码  
	for(i=0,j=0;i < len-2;j+=3,i+=4)  
	{  
		res[j]=((unsigned char)table[code[i]])<<2 | (((unsigned char)table[code[i+1]])>>4); //取出第一个字符对应base64表的十进制数的前6位与第二个字符对应base64表的十进制数的后2位进行组合  
		res[j+1]=(((unsigned char)table[code[i+1]])<<4) | (((unsigned char)table[code[i+2]])>>2); //取出第二个字符对应base64表的十进制数的后4位与第三个字符对应bas464表的十进制数的后4位进行组合  
		res[j+2]=(((unsigned char)table[code[i+2]])<<6) | ((unsigned char)table[code[i+3]]); //取出第三个字符对应base64表的十进制数的后2位与第4个字符进行组合  
	}  

	return res;  

} 

int socket_init(short port, char * ip)
{
	if(0 > port || NULL == ip)
	{
		puts("socket_init parameter error");
		return -1;
	}

	/*创建套接字描述符*/
	int socket_id = socket(AF_INET, SOCK_STREAM, 0);
	if(0 > socket_id)
	{
		perror("socket");
		return -1;
	}
	
	puts("socket success!!!");
	
	int on = 1;
	if ( 0 > setsockopt(socket_id, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) )
	{
		perror("set sock opt error, reUseAddr Error");
	}
	
	struct sockaddr_in addr = {
		.sin_family = AF_INET,
		.sin_port = htons(8080),
		.sin_addr = {
			.s_addr = inet_addr("172.25.4.221"),
		},
	};
	
	/*绑定端口号和ip地址*/
	if(0 > bind(socket_id, (struct sockaddr *)&addr, sizeof(addr)))
	{
		perror("bind");
		close(socket_id);
		return -1;
	}
	
	puts("bind success!!!");
	
	/*建立监听*/
	if(0 > listen(socket_id, 10))
	{
		perror("listen");
		close(socket_id);
		return -1;
	}

	puts("listen success!!!");

	return socket_id;
}


int accept_link(int socket_id, int epollfd)
{
	if(0 > socket_id || 0 > epollfd)
	{
		puts("accept_link parameter error");
		return -1;
	}

	struct sockaddr_in addr;
	int len = sizeof(addr);

	/*接受客户端连接请求*/
	int connect_id = accept(socket_id, (struct sockaddr *)&addr, &len);
	if(0 > connect_id)
	{
		perror("accept");
		close(socket_id);
		return -1;
	}

	struct epoll_event event = {
		.events = EPOLLIN,
		.data = {
			.fd = connect_id,
		},
	};
	
	client_id[user_id] = connect_id;
	user_id++;

	/*将通信套接字放入epoll监听链表中*/
	if(0 > epoll_ctl(epollfd, EPOLL_CTL_ADD, connect_id, &event))
	{
		perror("epoll_ctl");
		close(connect_id);
		return -1;
	}
	
	puts("client connect");	

	return 0;
}

int communication(int connect_id, int epollfd)
{
	if(0 > connect_id || 0 > epollfd)
	{
		perror("communication parameter error");
		return -1;
	}

	char buf[300] = {0};
	
	/*接收客户端发来的消息*/
	int ret = recv(connect_id, buf, SIZE - 1, 0);
	if(0 > ret)
	{
		perror("recv");
		return -1;
	}
	/*若发送的消息为空，说明客户端已经断开连接*/
	else if(0 == ret)
	{
		close(connect_id);
		/*将该客户端的通信套接字从监听链表中删除*/
		epoll_ctl(epollfd, EPOLL_CTL_DEL, connect_id, NULL);
		return -1;
	}	
	
	/*若收到的数据长度小于10，则是客户端发送过来的消息*/
	if(10 > strlen(buf))
	{
		client_id[0] = connect_id;
		
		
		sqlite3 *db;
		char *sql;
		
		/*初始化数据库*/
		db = sql_init(db);
		
		/*在数据库中查找该车辆编号*/
		ret = sql_table_find(db,buf);
		if(2 == ret)
		{
			printf("查找成功: %s\n",buf);
			ret = sql_table_update(db,buf);
				
			pthread_t pid;
			/*开启一个线程向云平台下发指令*/
			if(0 != pthread_create(&pid, NULL, do_work, (void *)&connect_id))
			{
				perror("pthread_create");
				return -1;
			}
		}
		else if(1 == ret)
		{
			strcpy(buf, "该车辆已开锁");
			send(connect_id, buf, sizeof(buf), 0);
		}
		else if(3 == ret)
		{
			strcpy(buf, "该车辆已损坏");
			send(connect_id, buf, sizeof(buf), 0);
		}
		else
		{
			strcpy(buf, "没有这个车辆");
			send(connect_id, buf, sizeof(buf), 0);
		}	
		sqlite3_close(db);
		
	}
	/*云平台发送过来的消息*/
	else
	{
		//printf("%s\n", buf);
		
		/*记录电信云发了多少次数据*/
		count++;
		//printf("count = %d\n", count);	
		
		/*回复电信云收到消息*/
		char str[] = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: 0\r\n\r\n";
		ret = send(connect_id, str, sizeof(str), 0);
		
		/*判断电信云发送的消息是否完成*/
		if(6 == count)		
		{
			count = 0;
		}
	
		/*电信云发来的第4次数据是我们需要处理的数据*/
		if(4 == count)
		{
			//printf("%s",buf);
			char * pAPPdata = strstr(buf, "APPdata");	
			
			char  pData[10] = {0};
			char ch = 0;
			int i = 0;

			//printf("pAPPData = %s\n", pAPPdata);
			printf("******************************************\n");
			/*解析HTTP报文，将数据获取出来*/
			while(1)
			{
				if(strncmp(pAPPdata,":",1) == 0)
				{
					while(strncmp(pAPPdata,"}", 1) != 0)	
					{
						pData[i] = *pAPPdata;
						i++;
						pAPPdata++;
						ch = *pAPPdata;		
					}
					break;
				}
				
				pAPPdata++;
			}
			
			int j = 0;
			int m = 0;
	
			for(j = 0; j < i; j++)	
			{
				if(0 == j)
				{	
					m += 2;
					pData[j] = pData[m];
				}
				else if(m >= i)
				{
					pData[j - 1] = '\0';
					break;	
				}
				else
				{
					pData[j] = pData[m];
				}

				m++;
			}
			
			printf("pdata=%s\n", pData);		
			
			unsigned char * data = NULL;
			unsigned char * ppData = pData;
			//char * ppData = pData;
	
			/*解码base64数据*/
			data = base64_decode(ppData);
			printf("data=%s\n", data);

			/*判断开锁是否成功*/		
			char msg[SIZE] = {0};
			if(strncmp(data, "OK", 2) == 0)
			{
				printf("开锁成功\n");
				strcpy(msg, "车辆开锁成功");
				//printf("client_id = %d\n", client_id[0]);
				ret = send(client_id[0], msg, sizeof(msg), 0);
				if(0 < ret)
				{
					printf("send to client success!!!\n");
				}	
			}
			else if(strncmp(data, "NG", 2) == 0)
			{
				printf("开锁失败\n");
				strcpy(msg, "车辆开锁失败");
				ret = send(client_id[0], msg, sizeof(msg), 0);
				if(0 < ret)
				{
					printf("send to client success!!!\n");
				}	
				
			}
			else if(strncmp(data, "cd", 2) == 0)
			{
				printf("车辆关锁\n");
				strcpy(msg, "该车辆已关锁");
				ret = send(client_id[0], msg, sizeof(msg), 0);
				if(0 < ret)
				{
					printf("send to client success!!!\n");
				}	

			}
			
			printf("******************************************\n");
	
			}
	}
	return 0;
}


void * do_work(void *arg)
{
	/*调用电信云python API接口向NB模块下发指令*/
	printf("=====================================================================================================\n");
	system("python aep_device_command_demo.py open");
	printf("==============================================指令下发成功===========================================\n");
	pthread_exit(NULL);
}





